package cn.iocoder.yudao.module.resource.controller.admin.audio;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.infra.service.file.FileService;
import cn.iocoder.yudao.module.infra.service.file.UploadFileResult;
import cn.iocoder.yudao.module.resource.controller.admin.audio.vo.DeleteAudioByIdsParam;
import cn.iocoder.yudao.module.resource.controller.admin.audio.vo.LmAudioPageReqVO;
import cn.iocoder.yudao.module.resource.controller.admin.audio.vo.LmAudioRespVO;
import cn.iocoder.yudao.module.resource.controller.admin.audio.vo.LmAudioSaveReqBatchVO;
import cn.iocoder.yudao.module.resource.controller.admin.audio.vo.LmAudioSaveReqVO;
import cn.iocoder.yudao.module.resource.dal.dataobject.audio.LmAudioDO;
import cn.iocoder.yudao.module.resource.service.audio.LmAudioService;
import cn.iocoder.yudao.module.resource.service.audiomark.AudioMarkService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 音频")
@RestController
@RequestMapping("/lm/audio")
@Validated
public class LmAudioController {

    @Resource
    private LmAudioService audioService;
    @Resource
    private AudioMarkService audioMarkService;
    @Resource
    private FileService fileService;

    @PostMapping("/create")
    @Operation(summary = "创建音频")
    @PreAuthorize("@ss.hasPermission('lm:audio:create')")
    public CommonResult<Integer> createAudio(@Valid @RequestBody LmAudioSaveReqVO createReqVO) {
        return success(audioService.createAudio(createReqVO));
    }

    @PostMapping("/createBatch")
    @Operation(summary = "批量创建音频")
    @PreAuthorize("@ss.hasPermission('lm:audio:create')")
    public CommonResult<List<Integer>> createAudioBatch(@Valid @RequestBody LmAudioSaveReqBatchVO createReqVO) {
        return success(audioService.createAudioBatch(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新音频")
    @PreAuthorize("@ss.hasPermission('lm:audio:update')")
    public CommonResult<Boolean> updateAudio(@Valid @RequestBody LmAudioSaveReqVO updateReqVO) {
        audioService.updateAudio(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除音频")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('lm:audio:delete')")
    public CommonResult<Boolean> deleteAudio(@RequestParam("id") Integer id) {
        audioService.deleteAudio(id);
        return success(true);
    }


    @PostMapping("/deleteByIds")
    @Operation(summary = "批量删除音频")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('lm:audio:delete')")
    public CommonResult<Boolean> deleteByIds(@RequestBody @Valid DeleteAudioByIdsParam param) {
        audioService.deleteAudio(param.getAudioIds());
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得音频")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('lm:audio:query')")
    public CommonResult<LmAudioRespVO> getAudio(@RequestParam("id") Integer id) {
        LmAudioDO audio = audioService.getAudio(id);
        LmAudioRespVO lmAudioRespVO = BeanUtils.toBean(audio, LmAudioRespVO.class);
        if (audio.getFileId() != null) {
            UploadFileResult uploadFileResult = fileService.getFile(audio.getFileId(), audio.getAudioTime());
            if (uploadFileResult != null) {
                lmAudioRespVO.setFileName(uploadFileResult.getFileName());
                lmAudioRespVO.setFileUrl(uploadFileResult.getFileUrl());
            }
        }
        if (audio.getAudioToneId() != null) {
            UploadFileResult uploadFileResult = fileService.getFile(audio.getAudioToneId().longValue(), (int) Duration.ofHours(1).toSeconds());
            if (uploadFileResult != null) {
                lmAudioRespVO.setAudioToneName(uploadFileResult.getFileName());
                lmAudioRespVO.setAudioToneUrl(uploadFileResult.getFileUrl());
            }
        }
        List<LmAudioRespVO> lmAudioRespVOS = Arrays.asList(lmAudioRespVO);
        audioMarkService.setTagAndKeyWord(lmAudioRespVOS);
        audioService.setRelationContent(lmAudioRespVOS);
        return success(lmAudioRespVO);
    }

    @GetMapping("/page")
    @Operation(summary = "获得音频分页")
    @PreAuthorize("@ss.hasPermission('lm:audio:query')")
    public CommonResult<PageResult<LmAudioRespVO>> getAudioPage(@Valid LmAudioPageReqVO pageReqVO) {
        PageResult<LmAudioDO> pageResult = audioService.getAudioPage(pageReqVO);

        PageResult<LmAudioRespVO> bean = BeanUtils.toBean(pageResult, LmAudioRespVO.class);
        List<Long> fileIds = bean.getList().stream().map(c -> c.getFileId()).collect(Collectors.toList());
        final Map<Long, Integer> resourceDurationSec = CollectionUtils.convertMap(bean.getList(), v -> v.getFileId(), v -> v.getAudioTime());
        List<UploadFileResult> fileResults = fileService.getFile(fileIds, resourceDurationSec);
        Map<Long, UploadFileResult> uploadFileResultMap = fileResults.stream()
                .collect(Collectors.toMap(UploadFileResult::getFileId, c -> c));
        for (LmAudioRespVO vo : bean.getList()) {
            UploadFileResult uploadFileResult = uploadFileResultMap.get(vo.getFileId());
            if (uploadFileResult != null) {
                vo.setFileName(uploadFileResult.getFileName());
                vo.setFileUrl(uploadFileResult.getFileUrl());
            }
            if (vo.getAudioToneId() != null) {
                uploadFileResult = fileService.getFile(vo.getAudioToneId().longValue(), (int) Duration.ofHours(1).toSeconds());
                if (uploadFileResult != null) {
                    vo.setAudioToneName(uploadFileResult.getFileName());
                    vo.setAudioToneUrl(uploadFileResult.getFileUrl());
                }
            }
        }
        audioMarkService.setTagAndKeyWord(bean.getList());
        audioService.setRelationContent(bean.getList());
        return success(bean);
    }
}